{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **LIBRARY IMPORT**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import wfdb as wf\n",
    "from wfdb import processing\n",
    "\n",
    "import neurokit2 as ECG\n",
    "import librosa as mi\n",
    "\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy import signal\n",
    "from scipy.fft import fft, ifft\n",
    "import numpy as np\n",
    "import os"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **FUNCTION DEFINITIONS**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def Feature_CC(segment):\n",
    "    try:\n",
    "        win = signal.windows.hamming(len(segment))\n",
    "        win_segment = np.multiply(segment, win)\n",
    "\n",
    "        fft_c = fft(win_segment,len(win_segment))\n",
    "        log_fft_c = np.log(np.abs(fft_c))\n",
    "        cc= ifft(log_fft_c)\n",
    "\n",
    "        return np.real(cc[:12])\n",
    "    except IndexError:\n",
    "        print(\"Index_error\")\n",
    "\n",
    "def Feature_Entropy(segment):\n",
    "\n",
    "\n",
    "    counts, _ = np.histogram(segment, bins=5)\n",
    "    P_x = counts/sum(counts)\n",
    "\n",
    "    entropy = sum(np.multiply(P_x,np.log2(P_x)))\n",
    "\n",
    "    return entropy\n",
    "        \n",
    "\n",
    "def Feature_ZCR(segment):\n",
    "    return np.sum(mi.zero_crossings(segment).astype(float))\n",
    "\n",
    "def ConvertArray2String(B):\n",
    "    Feature = \"\"\n",
    "    for i in B:\n",
    "        Feature = Feature + ',' +str(i)\n",
    "    return Feature\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **BASE DIRECTORY**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.chdir('..')\n",
    "dir = os.getcwd()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## **ECG_ID DATABASE**"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **FEATURE EXTRCATION: CHANNEL 0**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.chdir(dir)\n",
    "os.chdir(dir + '/DATASET/ECG-ID')\n",
    "IDs = os.listdir()\n",
    "print(IDs)\n",
    "\n",
    "# Channel number\n",
    "N = 0\n",
    "\n",
    "f = open(dir + '/Features' +'/'+ f\"Feature_ECG_ID_Channel_{N}.csv\", \"a\")\n",
    "f.write(\"ID,CC_1,CC_2,CC_3,CC_4,CC_5,CC_6,CC_7,CC_8,CC_9,CC_10,CC_11,CC_12,ENTROPY,ZCR,PERSON,TARGET\\n\")\n",
    "\n",
    "k=0\n",
    "for ID in IDs:\n",
    "    print(ID)\n",
    "    os.chdir(  os.getcwd()+ '/'+ ID)\n",
    "    Audio = os.listdir()\n",
    "    Audio_list = [k for k in Audio if '.dat' in k]\n",
    "\n",
    "\n",
    "\n",
    "    for A in Audio_list:\n",
    "        \n",
    "        print(A)\n",
    "        signal_array, fields = wf.rdsamp( os.getcwd() +  \"/\" + A.replace(\".dat\", \"\"))\n",
    "        sig = signal_array[:,N]\n",
    "\n",
    "        # For single channel\n",
    "        sos = signal.butter(6, [2, 50], btype='bandpass', fs=fields['fs'], analog= False)\n",
    "        filtered = signal.filtfilt(sos[0], sos[1], sig)\n",
    "\n",
    "        try:\n",
    "            _, rpeaks = ECG.ecg_peaks(filtered, sampling_rate=fields['fs'])\n",
    "            _, waves_peak = ECG.ecg_delineate(filtered, rpeaks, sampling_rate=1000, method=\"peak\")\n",
    "            t_peaks_ind = waves_peak['ECG_T_Peaks']\n",
    "        except IndexError:\n",
    "            print('Skipping' + A)\n",
    "            break\n",
    "        except TypeError:\n",
    "            print('Skipping' + A)\n",
    "            break\n",
    "        except ValueError:\n",
    "            print('Skipping' + A)\n",
    "            break\n",
    "        \n",
    "\n",
    "        for n in range(len(t_peaks_ind)-1):\n",
    "\n",
    "            try:\n",
    "                segment = filtered[int(t_peaks_ind[n]):int(t_peaks_ind[n+1])]\n",
    "                CC = Feature_CC(segment)\n",
    "                Entropy = Feature_Entropy(segment) \n",
    "                ZCR = Feature_ZCR(segment)\n",
    "\n",
    "                feature_string = ID + '_' + A.replace('.dat','') +'_' + str(n) + ConvertArray2String(CC) + ',' + str(Entropy) + ',' +  str(ZCR) + ',' + ID.replace('Person_','') + ',' + str(k) + '\\n'\n",
    "                f.write(feature_string)\n",
    "            except ValueError:\n",
    "                print('Skipping a segment')\n",
    "\n",
    "\n",
    "    os.chdir(dir + '/DATASET/ECG-ID')\n",
    "    k+=1\n",
    "\n",
    "f.close()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **FEATURE EXTRCATION: CHANNEL 1**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.chdir(dir)\n",
    "os.chdir(dir + '/DATASET/ECG-ID')\n",
    "IDs = os.listdir()\n",
    "print(IDs)\n",
    "\n",
    "# Channel number\n",
    "N = 1\n",
    "\n",
    "f = open(dir + '/Features' +'/'+ f\"Feature_ECG_ID_Channel_{N}.csv\", \"a\")\n",
    "f.write(\"ID,CC_1,CC_2,CC_3,CC_4,CC_5,CC_6,CC_7,CC_8,CC_9,CC_10,CC_11,CC_12,ENTROPY,ZCR,PERSON,TARGET\\n\")\n",
    "\n",
    "for ID in IDs:\n",
    "    print(ID)\n",
    "    os.chdir(  os.getcwd()+ '/'+ ID)\n",
    "    Audio = os.listdir()\n",
    "    Audio_list = [k for k in Audio if '.dat' in k]\n",
    "\n",
    "\n",
    "\n",
    "    for A in Audio_list:\n",
    "        \n",
    "        print(A)\n",
    "        signal_array, fields = wf.rdsamp( os.getcwd() +  \"/\" + A.replace(\".dat\", \"\"))\n",
    "        sig = signal_array[:,N]\n",
    "\n",
    "        # For single channel\n",
    "        sos = signal.butter(6, [2, 50], btype='bandpass', fs=fields['fs'], analog= False)\n",
    "        filtered = signal.filtfilt(sos[0], sos[1], sig)\n",
    "\n",
    "        try:\n",
    "            _, rpeaks = ECG.ecg_peaks(filtered, sampling_rate=fields['fs'])\n",
    "            _, waves_peak = ECG.ecg_delineate(filtered, rpeaks, sampling_rate=1000, method=\"peak\")\n",
    "            t_peaks_ind = waves_peak['ECG_T_Peaks']\n",
    "        except IndexError:\n",
    "            print('Skipping' + A)\n",
    "            break\n",
    "        except TypeError:\n",
    "            print('Skipping' + A)\n",
    "            break\n",
    "        except ValueError:\n",
    "            print('Skipping' + A)\n",
    "            break\n",
    "        \n",
    "\n",
    "        for n in range(len(t_peaks_ind)-1):\n",
    "\n",
    "            try:\n",
    "                segment = filtered[int(t_peaks_ind[n]):int(t_peaks_ind[n+1])]\n",
    "                CC = Feature_CC(segment)\n",
    "                Entropy = Feature_Entropy(segment) \n",
    "                ZCR = Feature_ZCR(segment)\n",
    "\n",
    "                feature_string = ID + '_' + A.replace('.dat','') +'_' + str(n) + ConvertArray2String(CC) + ',' + str(Entropy) + ',' +  str(ZCR) + ',' + ID.replace('Person_','') + ',' + str(k) + '\\n'\n",
    "                f.write(feature_string)\n",
    "            except ValueError:\n",
    "                print('Skipping a segment')\n",
    "\n",
    "    os.chdir(dir + '/DATASET/ECG-ID')\n",
    "\n",
    "f.close()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "sip-person_identification",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.15 | packaged by conda-forge | (default, Nov 22 2022, 08:49:35) \n[GCC 10.4.0]"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "0b6819903465b6f80edaece2a807aed469d8f41936c3b6c7b4bd5b116e5c55fc"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
